home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
print
/
pgraf130.zip
/
C.ZIP
/
PGRAFBUF.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-12
|
5KB
|
187 lines
/* File pgrafbuf.c */
/*---------------------------------------------------------------------------*
|
| Copyright (c) F van der Hulst 1991
| All Rights Reserved.
|
| Revisions:
| 26 June 1991: Added _p_getbyte() and _p_putbyte() to support model independence
| 10 October 1991: Virtual memory added by Dieter Gugeler
*
*---------------------------------------------------------------------------*/
#ifdef __TURBOC__
#include <alloc.h>
#else
#include <sys\types.h>
#include <malloc.h>
#endif
#include <stdio.h>
#include <io.h>
#include <fcntl.h>
#include <sys\stat.h>
#include "pgraph.h"
#define TRUE 1
#define FALSE 0
#define HEAPMEMLEFT 2048 /* Leave 2 KBYTE free on the heap */
#define MIN_BLOCK_SIZE 512 /* Minimum block size */
#define PRTTEMPFILE "prt001.$$$"
static char huge * far_buffer;
#ifdef VIRT_MEM
static char * near_buffer;
static unsigned int block_size;
static unsigned int curr_block;
static int handle;
static char disk_buffer;
static char buffer_changed;
static int pascal near initvdsk(unsigned long int size)
{
unsigned int num_blocks;
unsigned int ll;
unsigned long int free_space;
free_space = farcoreleft() - HEAPMEMLEFT; /* Leave room for other graph memory uses */
if (size > free_space) {
free_space = coreleft() - HEAPMEMLEFT; /* Can't do it on far heap -- use near heap */
if (free_space > 0xff00) block_size = 0xff00;
else block_size = (unsigned int) free_space;
if (block_size < MIN_BLOCK_SIZE) return FALSE;
num_blocks = (unsigned int) ((size + block_size - 1) / block_size);
printf("Allocating %ud disk buffers of 0x%x bytes\n", num_blocks, block_size);
remove(PRTTEMPFILE);
if ((handle = open(PRTTEMPFILE, O_CREAT | O_BINARY | O_TRUNC, S_IREAD | S_IWRITE)) == -1)
return FALSE;
if ((near_buffer = malloc(block_size)) == NULL) return FALSE;
for (ll=0; ll <= num_blocks; ll++)
if ((write(handle, near_buffer, block_size)) == -1) return FALSE;
curr_block = 0;
disk_buffer = TRUE;
} else far_buffer = farmalloc(size);
return TRUE;
}
static void pascal near closevdsk(void)
{
close(handle);
remove(PRTTEMPFILE);
disk_buffer = FALSE;
}
static void pascal near writevdsk(unsigned int blocknum)
{
lseek(handle, (long)block_size * blocknum, SEEK_SET);
write(handle, near_buffer, block_size);
buffer_changed = FALSE;
}
static void pascal near readvdsk(unsigned int blocknum)
{
if (buffer_changed) writevdsk(curr_block);
lseek(handle, (long)block_size * blocknum, SEEK_SET);
read(handle, near_buffer, block_size);
curr_block = blocknum;
}
#endif
static unsigned char FUNC_TYPE pgr_getbyte(unsigned long int offset)
{
#ifdef VIRT_MEM
unsigned int blocknum;
if (disk_buffer) {
if ((blocknum = (unsigned) (offset / block_size)) != curr_block)
readvdsk(blocknum);
return near_buffer[(unsigned int)(offset-(long)blocknum*block_size)];
}
#endif
return far_buffer[offset];
}
static void FUNC_TYPE pgr_putbyte(unsigned long int offset, unsigned char byte)
{
#ifdef VIRT_MEM
unsigned int blocknum;
if (disk_buffer) {
if ((blocknum = (unsigned) (offset / block_size)) != curr_block)
readvdsk(blocknum);
near_buffer[(unsigned int)(offset-((long)blocknum * block_size))] = byte;
buffer_changed = TRUE;
return;
}
#endif
far_buffer[offset] = byte;
}
#if defined(__TURBOC__)
/* The following two routines are required in any 64K Code model, since
_p_graphgetmem and _p_graphfreemem MUST point to a HUGE function, and
in small code model libraries, these functions are NEAR */
static void FUNC_TYPE pgr_graphfreemem(void far *ptr, unsigned long size)
{
farfree(ptr);
#pragma warn -par
}
#pragma warn .par
static void far * FUNC_TYPE pgr_graphgetmem(unsigned long size)
{
return farmalloc(size);
}
#else
static void far * FUNC_TYPE pgr_graphgetmem(unsigned long size)
{
return halloc(size, 1);
}
static void FUNC_TYPE pgr_graphfreemem(void far *ptr, unsigned long size)
{
hfree(ptr);
}
#endif
static int FUNC_TYPE pgr_graphgetbuff(unsigned long size)
{
#ifdef VIRT_MEM
return initvdsk(size);
#else
return (far_buffer = pgr_graphgetmem(size)) != NULL;
#endif
}
static void FUNC_TYPE pgr_graphfreebuff(unsigned long size)
{
#ifdef VIRT_MEM
if (disk_buffer) {
closevdsk();
free(near_buffer);
} else pgr_graphfreemem((void far *)far_buffer, size);
#else
pgr_graphfreemem((void far *)far_buffer, size);
#endif
}
void init_buffering(void)
{
_p_graphgetmem = pgr_graphgetmem;
_p_graphfreemem = pgr_graphfreemem;
_p_graphgetbuff = pgr_graphgetbuff;
_p_graphfreebuff = pgr_graphfreebuff;
_p_putbyte = pgr_putbyte;
_p_getbyte = pgr_getbyte;
}